﻿
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Xml.Linq;

namespace TreservaDeployHelper
{
    public static class XmlHelper
    {
        public static XDocument CreateNewDocument()
        {
            XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
            XNamespace xsd = "http://www.w3.org/2001/XMLSchema";
            var xDeclaration = new XDeclaration("1.0", "utf-8", "");
            var xElement = new XElement("DeployServerConfig", new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), new XAttribute(XNamespace.Xmlns + "xsd", xsd.NamespaceName));

            return new XDocument(xDeclaration, xElement);
        }

        public static XElement GetApplicationNode(XElement deployServerConfig)
        {
            XElement Application = deployServerConfig.Element("Application");

            if (Application == null)
            {
                deployServerConfig.Add(new XElement("Application"));

                return deployServerConfig.Element("Application");
            }

            return Application;
        }

        public static XElement GetApplicationChildNodes(XElement application, string nodeName)
        {
            XElement ApplicationChildNode = application.Element(nodeName);

            if (ApplicationChildNode == null)
            {
                application.Add(new XElement(nodeName));

                return application.Element(nodeName);
            }

            return ApplicationChildNode;
        }

        public static XElement GetApplicationHostChildNodes(XElement applicationHost, string nodeName)
        {
            XElement ApplicationHostChildNode = applicationHost.Element(nodeName);

            if (ApplicationHostChildNode == null)
            {
                applicationHost.Add(new XElement(nodeName));

                return applicationHost.Element(nodeName);
            }

            return ApplicationHostChildNode;
        }

        public static XElement GetWebServerChildNodes(XElement webServer, string nodeName)
        {
            XElement WebServerChildNode = webServer.Element(nodeName);

            if (WebServerChildNode == null)
            {
                webServer.Add(new XElement(nodeName));

                return webServer.Element(nodeName);
            }

            return WebServerChildNode;
        }

        public static XElement GetApplicationServerChildNodes(XElement applicationServer, string nodeName)
        {
            XElement ApplicationServerChildNode = applicationServer.Element(nodeName);

            if (ApplicationServerChildNode == null)
            {
                applicationServer.Add(new XElement(nodeName));

                return applicationServer.Element(nodeName);
            }

            return ApplicationServerChildNode;
        }

        public static List<XElement> GetWinServicesChildNodes(XElement winServices, int defaultNumberOfWinServices)
        {
            int count = winServices.Descendants("WinService").Count();

            if (count < defaultNumberOfWinServices)
            {
                int missingNodes = defaultNumberOfWinServices - count;

                for (int i = 0; i < missingNodes; i++)
                {
                    winServices.Add(new XElement("WinService"));
                }

                return winServices.Descendants("WinService").ToList();
            }

            return winServices.Descendants("WinService").ToList();
        }

        public static List<XElement> GetDatabasesChildNodes(XElement databases, int defaultNumberDatabases)
        {
            int count = databases.Descendants("Database").Count();

            if (count < defaultNumberDatabases)
            {
                int missingNodes = defaultNumberDatabases - count;

                for (int i = 0; i < missingNodes; i++)
                {
                    databases.Add(new XElement("Database"));
                }

                return databases.Descendants("Database").ToList();
            }

            return databases.Descendants("Database").ToList();
        }

        public static XElement GetIntegrationChildNodes(XElement integration, string nodeName)
        {
            XElement IntegrationChildNode = integration.Element(nodeName);

            if (IntegrationChildNode == null)
            {
                integration.Add(new XElement(nodeName));

                return integration.Element(nodeName);
            }

            return IntegrationChildNode;
        }

        public static XElement GetIntegrationStarterChildNodes(XElement integrationStarter, string nodeName)
        {
            XElement IntegrationStarterChildNode = integrationStarter.Element(nodeName);

            if (IntegrationStarterChildNode == null)
            {
                integrationStarter.Add(new XElement(nodeName));

                return integrationStarter.Element(nodeName);
            }

            return IntegrationStarterChildNode;
        }

        #region Old Code.

        //public static XElement CheckApplicationHosts(XElement application)
        //{
        //    XElement ApplicationHosts = application.Element("ApplicationHosts");

        //    if (ApplicationHosts == null)
        //    {
        //        application.Add(new XElement("ApplicationHosts"));

        //        return application.Element("ApplicationHosts");
        //    }

        //    return ApplicationHosts;
        //}

        //public static XElement CheckApplicationSource(XElement application)
        //{
        //    XElement ApplicationSource = application.Element("ApplicationSource");

        //    if (ApplicationSource == null)
        //    {
        //        application.Add(new XElement("ApplicationSource"));

        //        return application.Element("ApplicationSource");
        //    }

        //    return ApplicationSource;
        //}

        //public static XElement CheckWinServices(XElement application)
        //{
        //    XElement WinServices = application.Element("WinServices");

        //    if (WinServices == null)
        //    {
        //        application.Add(new XElement("WinServices"));

        //        return application.Element("WinServices");
        //    }

        //    return WinServices;
        //}

        //public static XElement CheckDatabases(XElement application)
        //{
        //    XElement Databases = application.Element("Databases");

        //    if (Databases == null)
        //    {
        //        application.Add(new XElement("Databases"));

        //        return application.Element("Databases");
        //    }

        //    return Databases;
        //}

        //public static XElement CheckIntegration(XElement application)
        //{
        //    XElement Integration = application.Element("Integration");

        //    if (Integration == null)
        //    {
        //        application.Add(new XElement("Integration"));

        //        return application.Element("Integration");
        //    }

        //    return Integration;
        //}

        //public static XElement CheckWebServer(XElement applicationHosts)
        //{
        //    XElement WebServer = applicationHosts.Element("WebServer");

        //    if (WebServer == null)
        //    {
        //        applicationHosts.Add(new XElement("WebServer"));

        //        WebServer = applicationHosts.Element("WebServer");

        //        return WebServer;
        //    }

        //    return WebServer;
        //}

        //public static XElement CheckWinServicesServer(XElement applicationHosts)
        //{
        //    XElement WinServicesServer = applicationHosts.Element("WinServicesServer");

        //    if (WinServicesServer == null)
        //    {
        //        applicationHosts.Add(new XElement("WinServicesServer"));

        //        WinServicesServer = applicationHosts.Element("WinServicesServer");

        //        return WinServicesServer;
        //    }

        //    return WinServicesServer;
        //}

        //public static XElement CheckApplicationServer(XElement applicationHosts)
        //{
        //    XElement ApplicationServer = applicationHosts.Element("ApplicationServer");

        //    if (ApplicationServer == null)
        //    {
        //        applicationHosts.Add(new XElement("ApplicationServer"));

        //        ApplicationServer = applicationHosts.Element("ApplicationServer");

        //        return ApplicationServer;
        //    }

        //    return ApplicationServer;
        //}

        //public static XElement CheckTreservaAdapter(XElement integration)
        //{
        //    XElement TreservaAdapter = integration.Element("TreservaAdapter");

        //    if (TreservaAdapter == null)
        //    {
        //        integration.Add(new XElement("TreservaAdapter"));

        //        return integration.Element("TreservaAdapter");
        //    }

        //    return TreservaAdapter;
        //}

        //public static XElement CheckTreservaPocket(XElement integration)
        //{
        //    XElement TreservaPocket = integration.Element("TreservaPocket");

        //    if (TreservaPocket == null)
        //    {
        //        integration.Add(new XElement("TreservaPocket"));

        //        return integration.Element("TreservaPocket");
        //    }

        //    return TreservaPocket;
        //}

        //public static XElement CheckIntegrationStarter(XElement integration)
        //{
        //    XElement IntegrationStarter = integration.Element("IntegrationStarter");

        //    if (IntegrationStarter == null)
        //    {
        //        integration.Add(new XElement("IntegrationStarter"));

        //        return integration.Element("IntegrationStarter");
        //    }

        //    return IntegrationStarter;
        //}

        //public static XElement CheckTreservaArchiveIntegrationService(XElement integrationStarter)
        //{
        //    XElement TreservaArchiveIntegrationService = integrationStarter.Element("TreservaArchiveIntegrationService");

        //    if (TreservaArchiveIntegrationService == null)
        //    {
        //        integrationStarter.Add(new XElement("TreservaArchiveIntegrationService"));

        //        return integrationStarter.Element("TreservaArchiveIntegrationService");
        //    }

        //    return TreservaArchiveIntegrationService;
        //}

        //public static XElement CheckTreservaCareIntegrationService(XElement integrationStarter)
        //{
        //    XElement TreservaCareIntegrationService = integrationStarter.Element("TreservaCareIntegrationService");

        //    if (TreservaCareIntegrationService == null)
        //    {
        //        integrationStarter.Add(new XElement("TreservaCareIntegrationService"));

        //        return integrationStarter.Element("TreservaCareIntegrationService");
        //    }

        //    return TreservaCareIntegrationService;
        //}

        //public static XElement CheckTreservaEServiceIntegrationService(XElement integrationStarter)
        //{
        //    XElement TreservaEServiceIntegrationService = integrationStarter.Element("TreservaEServiceIntegrationService");

        //    if (TreservaEServiceIntegrationService == null)
        //    {
        //        integrationStarter.Add(new XElement("TreservaEServiceIntegrationService"));

        //        return integrationStarter.Element("TreservaEServiceIntegrationService");
        //    }

        //    return TreservaEServiceIntegrationService;
        //}

        //public static XElement CheckTreservaTGPIntegrationService(XElement integrationStarter)
        //{
        //    XElement TreservaTGPIntegrationService = integrationStarter.Element("TreservaTGPIntegrationService");

        //    if (TreservaTGPIntegrationService == null)
        //    {
        //        integrationStarter.Add(new XElement("TreservaTGPIntegrationService"));

        //        return integrationStarter.Element("TreservaTGPIntegrationService");
        //    }

        //    return TreservaTGPIntegrationService;
        //}

        //public static XElement CheckIntegrationStarterTES(XElement integrationStarter)
        //{
        //    XElement IntegrationStarterTES = integrationStarter.Element("IntegrationStarterTES");

        //    if (IntegrationStarterTES == null)
        //    {
        //        integrationStarter.Add(new XElement("IntegrationStarterTES"));

        //        return integrationStarter.Element("IntegrationStarterTES");
        //    }

        //    return IntegrationStarterTES;
        //}

        //public static XElement CheckIntegrationStarterMobipen(XElement integrationStarter)
        //{
        //    XElement IntegrationStarterMobipen = integrationStarter.Element("IntegrationStarterMobipen");

        //    if (IntegrationStarterMobipen == null)
        //    {
        //        integrationStarter.Add(new XElement("IntegrationStarterMobipen"));

        //        return integrationStarter.Element("IntegrationStarterMobipen");
        //    }

        //    return IntegrationStarterMobipen;
        //}

        //public static XElement CheckIntegrationStarterCardEmbossing(XElement integrationStarter)
        //{
        //    XElement IntegrationStarterCardEmbossing = integrationStarter.Element("IntegrationStarterCardEmbossing");

        //    if (IntegrationStarterCardEmbossing == null)
        //    {
        //        integrationStarter.Add(new XElement("IntegrationStarterCardEmbossing"));

        //        return integrationStarter.Element("IntegrationStarterCardEmbossing");
        //    }

        //    return IntegrationStarterCardEmbossing;
        //}

        //public static XElement CheckIntegrationStarterHealthcare(XElement integrationStarter)
        //{
        //    XElement IntegrationStarterHealthcare = integrationStarter.Element("IntegrationStarterHealthcare");

        //    if (IntegrationStarterHealthcare == null)
        //    {
        //        integrationStarter.Add(new XElement("IntegrationStarterHealthcare"));

        //        return integrationStarter.Element("IntegrationStarterHealthcare");
        //    }

        //    return IntegrationStarterHealthcare;
        //}

        //public static XElement CheckIntegrationStarterRefugee(XElement integrationStarter)
        //{
        //    XElement IntegrationStarterRefugee = integrationStarter.Element("IntegrationStarterRefugee");

        //    if (IntegrationStarterRefugee == null)
        //    {
        //        integrationStarter.Add(new XElement("IntegrationStarterRefugee"));

        //        return integrationStarter.Element("IntegrationStarterRefugee");
        //    }

        //    return IntegrationStarterRefugee;
        //}

        #endregion
    }

    public static class ExtensionMethods
    {
        //This method is to handle if element is missing
        public static string ElementValueNull(this XElement element)
        {
            if (element != null)
            {
                return element.Value;
            }
                

            return "";
        }

        //This method is to handle if attribute is missing
        public static string AttributeValueNull(this XElement element, string attributeName)
        {
            if (element == null)
                return "";
            else
            {
                XAttribute attr = element.Attribute(attributeName);
                return attr == null ? "" : attr.Value;
            }
        }

        public static IEnumerable<T> AllControls<T>(this Control startingPoint) where T : Control
        {
            bool hit = startingPoint is T;
            if (hit)
            {
                yield return startingPoint as T;
            }
            foreach (var child in startingPoint.Controls.Cast<Control>())
            {
                foreach (var item in AllControls<T>(child))
                {
                    yield return item;
                }
            }
        }

        public static IEnumerable<T> Descendants<T>(this Control control) where T : class
        {

            foreach (Control child in control.Controls)
            {

                T childOfT = child as T;
                if (childOfT != null)
                {
                    yield return (T)childOfT;
                }

                if (child.HasChildren)
                {
                    foreach (T descendant in Descendants<T>(child))
                    {
                        yield return descendant;
                    }
                }
            }
        } 
    }
}
